<?php

class NCore_CompositePort implements NCore_IPort
{
	private $name = NULL;
    private $components = array();
    private $ports = array();
	private $value = NULL;
	private $valid = NULL;
    private $errorMsg = NULL;

	public function __construct($key, $components)
    {
        $this->name = $key;

        if (!is_array($components)) throw new Exception('The second argument of the NCore_CompositePort class must be an array.');

        $this->components = $components;
    }
	public function validate()
    {
        if(!is_null($this->valid))
            return $this->valid;

        $valid = true;

        foreach($this->getPorts() as $port)
        {
            if(!$port->isValid())
            {
                return $this->valid = false;
            }
        }

        return $this->valid = true;
    }
    public function isPresent()
    {
        foreach($this->getPorts() as $p)
        {
            if(!$p->isPresent())
                return false;
        }

        return true;
    }
	public function isValid()
    {
       return $this->validate();
    }
    public function getPorts()
    {
        if(count($this->ports) > 1)
            return $this->ports;

        foreach($this->components as $comp)
        {
            if($comp instanceof NCore_IPort)
            {
                $this->ports[$comp->getName()] = $comp;
            }
        }

        return $this->ports;
    }
    public function withErrorMsg($msg)
	{
		$this->errorMsg = $msg;
		return $this;
	}
	public function getErrorMsg()
	{
        if(is_null($this->errorMsg))
            return 'The data for the '.$this->name.' field is invalid.';

		return $this->errorMsg;
	}
    public function getValue()
    {
        if(is_null($this->valid))
            throw new Exception('The composite port \''.$this->name.'\' must be validated through the isValid() method before you can retrieve its value.');

        if(!$this->valid)
            throw new Exception('The composite port \''.$this->name.'\' is not valid, so no value is available.');

        if(!is_null($this->value))
            return $this->value;

        $value = '';

        foreach($this->components as $comp)
        {
            if($comp instanceof NCore_IPort)
            {
                $value .= $comp->getValue();
            }
            else
            {
                $value .= $comp;
            }
        }

        return $this->value = $value;
    }
    function __toString()
    {
        return $this->getValue();
    }
}

?>
